#include "iot_cloud.h"
#include "iot_profile.h"
#include "iot_boardled.h"
#include "iot_boardbutton.h"
#include "iot_nfc.h"
#include "iot_wifi.h"
#include "iot_netcfg.h"
#include "iot_sntp.h"
#include "ohos_init.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <cmsis_os2.h>
#include <stdbool.h>
#include "kv_store.h"
#include "iot_schedule.h"
#include "iot_netcfg_nan.h"
#include "network_config_service.h"
#include "hi_reset.h"
#include "button_control.h"
#include "SW_18010P.h"


#define SID_KEY "ssid"
#define PWD_KEY "password"

#define SOFTAP_NAME "teamX-Vibra01"

// DEFAULT PARAM, AND MUST BE MODIFIED TO THE REAL PARAMS
#define CONFIG_CLOUD_DEFAULT_SERVERIP "121.36.42.100" // replace it with iotplatform server ip
#define CONFIG_CLOUD_DEFAULT_SERVERPORT "1883"          // replace it with iotplatform server  port
#define CONFIG_SENSOR_SAMPLE_CYCLE 10000              // unit:minisecond
#define CONFIG_TASK_DEFAULT_STACKSIZE 0x1000          // unit:bytes
#define CONFIG_TASK_DEFAULT_PRIOR 20                  // default task priority
#define CONFIG_TASK_MAIN_STACKSIZE 0x4000              // main task stacksize must be bigger
#define CONFIG_TASK_MAIN_PRIOR 25                      // default task priority
#define CONFIG_LOCAL_TIMEZONE 8
#define CONFIG_LED_DUTYCYCLEDEFAULT 20
#define CONFIG_LED_DUTYMAXMUN 99
#define CONFIG_LED_DUTYMINIMUM 1
#define CONFIG_FLASHLED_FRENETCONFIG 8
#define CONFIG_FLASHLED_FREWIFI 4
#define CONFIG_FLASHLED_FRECLOUD 1
#define CONFIG_FLASHLED_WORKSWELL 0.1

extern g_wifi_status;

#define CN_LAMP_EVENT_SETSTATUS (1 << 0)
#define CN_LAMP_EVENT_SETDUTY (1 << 1)
#define CN_LAMP_EVENT_ALL (CN_LAMP_EVENT_SETSTATUS | CN_LAMP_EVENT_SETDUTY)

#define CN_REACTION_TIME_SECONDS 1

static void SensorTaskEntry(const void *arg)
{
    (void)arg;
    int reportCount = 0;
	RaiseLog(LOG_LEVEL_INFO, "run thread SensorTaskEntry!");
    SW18010PInit();
    while (1) {
        if(SW18010PGet() == SW18010_ON) {
            IotProfile_Report(DETECT_ON);
            CLOUD_ReportNotification(NOTIFY_TYPE_URGENT, " Your safe may be pried. Please check it! ", "您的保险柜可能被撬动，请注意查看");
            reportCount = 0;
        } else {
            reportCount++;
            if (reportCount > 300) { //30s 
                IotProfile_Report(DETECT_OFF);
                reportCount = 0;
            }
        }
        osDelay(10);
    }
    return;
}


/**
 * @brief Callback function used to process commands delivered by the Cloud Platform
 * @param command Indicates the command delivered by the Cloud Platform
 * @param value Indicates the parameter corresponding to the command
 * @return Returns 0 success while -1 failed
 */
int IotProfile_CommandCallback(int command, void *buf)
{
    CLOUD_CommandType cmd = (CLOUD_CommandType)command;

    RaiseLog(LOG_LEVEL_INFO,"GET CMD ->%d", cmd);
    return 0;
}

static int IotWifiInfo_get(char *ssid, int id_size, char *pwd, int pd_size)
{
    int retval = UtilsGetValue(SID_KEY, ssid, id_size);
    if (retval <= 0)
    {
        RaiseLog(LOG_LEVEL_ERR, "no such ssid stored! \n");
        return 0;
    }

    if (UtilsGetValue(PWD_KEY, pwd, pd_size) < 0)
    {
        RaiseLog(LOG_LEVEL_INFO, "ssid(%s) no password stored! \n", ssid);
    }
    else
    {
        RaiseLog(LOG_LEVEL_INFO, "ssid : %s, pwd : %s! \n", ssid, pwd);
    }

    return 1;
}

static void IotWifiInfo_set(char *ssid, char *pwd)
{
    if (UtilsSetValue(SID_KEY, ssid) != 0)
    {
        RaiseLog(LOG_LEVEL_ERR, "store ssid failed! \n");
        return;
    }
    if (UtilsSetValue(PWD_KEY, pwd) != 0)
    {
        RaiseLog(LOG_LEVEL_ERR, "store password failed! \n");
        UtilsDeleteValue(SID_KEY);
        return;
    }
    RaiseLog(LOG_LEVEL_INFO, "store password success! \n");
}
/**
 * @brief IoTMain task entry and the main flow is as follows:
 *        1, Initialize the necessary hardware and obtain the corresponding information from NFC
 *        2, Connecting to wifi
 *        3, Connecting to the HUAWEI CLOUD Platform
 *        4, Creating a Sensor Collection Task
 */
static void IotMainTaskEntry(const void *arg)
{
    osThreadAttr_t attr;
    NfcInfo nfcInfo;
    (void)arg;
    char ssid[BUFF_SIZE] = {0};
    char pwd[BUFF_SIZE] = {0};
    int ret;
    
	switch_init();
    BOARD_InitWifi();
    IOT_ScheduleInit();
	
    nfcInfo.deviceID = "61bc57222b2aa20288caf888_Vibra01";
    nfcInfo.devicePWD = "12345678";

     g_wifi_status = CAR_WIFI_CONNECT_ING;

    ret=get_gpio5_voltage();
    RaiseLog(LOG_LEVEL_ERR, "get_gpio5_voltage->%d", ret);
    if (ret)
    {
        RaiseLog(LOG_LEVEL_INFO, "Netconfig Button has pressed! \n");
        if(BOARD_NAN_NetCfgStartConfig(SOFTAP_NAME, ssid, sizeof(ssid), pwd, sizeof(pwd)) < 0)  
        {
            RaiseLog(LOG_LEVEL_ERR, "BOARD_NetCfgStartConfig failed! \n");
            return;
        }
        ret = 0;
    }
    else
    {
        ret = IotWifiInfo_get(ssid, sizeof(ssid), pwd, sizeof(pwd));
        if (ret == 0)
        {
            if(BOARD_NAN_NetCfgStartConfig(SOFTAP_NAME, ssid, sizeof(ssid), pwd, sizeof(pwd)) < 0)
            {
                RaiseLog(LOG_LEVEL_ERR, "BOARD_NetCfgStartConfig failed! \n");
                return;
            }
        }
    }
    
    if (BOARD_ConnectWifi(ssid, pwd) != 0)
    {
        RaiseLog(LOG_LEVEL_ERR, "BOARD_ConnectWifi failed! \n");
        NotifyNetCfgResult(NETCFG_DEV_INFO_INVALID);
        hi_hard_reboot(HI_SYS_REBOOT_CAUSE_CMD);
        return;
    }
    g_wifi_status = CAR_WIFI_CONNECT_OK;
    if (ret == 0)
    {
        RaiseLog(LOG_LEVEL_DEBUG, "Connect wifi success ! \n");
        NotifyNetCfgResult(NETCFG_OK);
        osDelay(100);
        RaiseLog(LOG_LEVEL_DEBUG, "StopNetCfg wifi success ! \n");
        StopNetCfg();
        IotWifiInfo_set(ssid, pwd);
    }

    if (CLOUD_Init() != 0)
    {
        return;
    }

    if (CLOUD_Connect(nfcInfo.deviceID, nfcInfo.devicePWD,
                      CONFIG_CLOUD_DEFAULT_SERVERIP, CONFIG_CLOUD_DEFAULT_SERVERPORT) != 0)
    {
        return;
    }
    g_wifi_status = CAR_IOT_CONNECT_OK;
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = CONFIG_TASK_DEFAULT_STACKSIZE;
    attr.priority = CONFIG_TASK_DEFAULT_PRIOR;
    attr.name = "DataCollectAndReport";

    (void)osThreadNew((osThreadFunc_t)SensorTaskEntry, NULL, (const osThreadAttr_t *)&attr);
    return;
}

/**
 * @brief IoT Main Entry of the IoT-Flower project
 */
static void IotMainEntry(void)
{
    osThreadAttr_t attr;
    RaiseLog(LOG_LEVEL_INFO, "DATA:%s Time:%s \r\n", __FUNCTION__, __DATE__, __TIME__);
    // Create the IoT Main task
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = CONFIG_TASK_MAIN_STACKSIZE;
    attr.priority = CONFIG_TASK_MAIN_PRIOR;
    attr.name = "IoTMain";
    (void)osThreadNew((osThreadFunc_t)IotMainTaskEntry, NULL, (const osThreadAttr_t *)&attr);

    return;
}
// Add the IotMainEntry function to the System Startup Procedure
APP_FEATURE_INIT(IotMainEntry);
